package com.itheima.service.impl;

import com.itheima.dao.AdminDao;
import com.itheima.dao.OrderDao;
import com.itheima.dao.ProductDao;
import com.itheima.dao.UserDao;
import com.itheima.domain.*;
import com.itheima.service.AdminService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Service
public class AdminServiceImpl implements AdminService {
    @Autowired
    private AdminDao adminDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private ProductDao productDao;
    @Autowired
    private OrderDao orderDao;

    @Override
    public Admin authenticate(String username, String password) {
        Admin admin = adminDao.findByUsername(username);
        if (admin != null && admin.getPassword().equals(password)) {
            return admin;
        }
        return null;
    }

    @Override
    public Admin findAdminByUsername(String username) {
        return adminDao.findByUsername(username);
    }

    @Override
    public AdminStatsVO getAdminStats() {
        AdminStatsVO stats = new AdminStatsVO();

        // 1. 新增用户统计（对比昨日）
        int todayNewUsers = adminDao.getTodayNewUserCount();
        stats.setNewuserCount(todayNewUsers);
        int yesterdayNewUsers = adminDao.getYesterdayNewUserCount();
        stats.setNewuserGrowth(calculateGrowth(todayNewUsers, yesterdayNewUsers));

        // 2. 商品统计（对比昨日）
        int todayNewProducts = adminDao.getTodayNewProductCount();
        stats.setNewproductCount(todayNewProducts);
        int yesterdayNewProducts = adminDao.getYesterdayNewProductCount();
        stats.setNewproductGrowth(calculateGrowth(todayNewProducts, yesterdayNewProducts));

        // 3. 订单统计（对比昨日）
        int todayOrderCount = adminDao.getTodayOrderCount();
        stats.setTodayOrderCount(todayOrderCount);
        int yesterdayOrderCount = adminDao.getYesterdayOrderCount();
        stats.setTodayOrderGrowth(calculateGrowth(todayOrderCount, yesterdayOrderCount));

        // 4. 销售额统计（对比昨日）
        Double todaySales = adminDao.getTodaySales();
        stats.setTodaySales(todaySales != null ? todaySales : 0.0);
        Double yesterdaySales = adminDao.getYesterdaySales();
        stats.setTodaySalesGrowth(calculateGrowth(todaySales, yesterdaySales));

        return stats;
    }

    // 通用增长率计算方法（处理null/零值）
    private Double calculateGrowth(Number current, Number previous) {
        if (current == null || previous == null) return 0.0;
        double curr = current.doubleValue();
        double prev = previous.doubleValue();
        if (prev == 0) return curr > 0 ? 100.0 : 0.0;
        return (curr - prev) * 100.0 / prev;
    }

    @Override
    public List<AdminActivityVO> getRecentActivities(int count) {
        return adminDao.getRecentActivities(count);
    }

    @Override
    public List<Double> getWeeklySalesData() {
        Map<Integer, Map<String, Object>> weeklyData = adminDao.getWeeklySalesData();
        List<Double> result = new ArrayList<>(7);

        // MySQL中周日是1，周一是2...周六是7
        // 我们调整为周一到周日(2-8)
        for (int i = 2; i <= 8; i++) {
            if (weeklyData.containsKey(i)) {
                result.add(((Number) weeklyData.get(i).get("total")).doubleValue());
            } else {
                result.add(0.0);
            }
        }
        return result;
    }

    @Override
    public List<String> getCategoryNames() {
        // 确保分类名称按categoryId排序
        return adminDao.getCategoryNames();
    }

    @Override
    public List<Double> getCategorySalesData() {
        List<Map<String, Object>> rawData = adminDao.getCategorySalesDataWithZero();
        List<Double> result = new ArrayList<>();

        for (Map<String, Object> item : rawData) {
            // 直接取total（LEFT JOIN + IFNULL已保证不为null）
            result.add(((Number) item.get("total")).doubleValue());
        }

        return result;
    }

    @Override
    public List<Integer> getMonthlyLabels() {
        // 直接返回1-31日，无需查数据库
        return IntStream.rangeClosed(1, 31)
                .boxed()
                .collect(Collectors.toList());
    }

    @Override
    public List<User> getAllUsers() {
        return adminDao.findAllUsers();
    }

    @Override
    public List<Product> getAllProducts() {
        return adminDao.findAllProducts();
    }

    @Override
    public List<Order> getAllOrders() {
        return adminDao.findAllOrders();
    }

    @Override
    public List<Category> getAllCategories() {
        return adminDao.findAllCategories();
    }

    @Override
    public List<BigDecimal> getMonthlySalesData() {
        // 1. 查询实际销售数据（可能只返回部分日期）
        List<Map<String, Object>> rawData = adminDao.getMonthlySales();

        // 2. 初始化一个长度为31的LinkedHashMap，默认值为0
        Map<Integer, BigDecimal> salesMap = new LinkedHashMap<>();
        for (int day = 1; day <= 31; day++) {
            salesMap.put(day, BigDecimal.ZERO);
        }

        // 3. 将查询到的销售数据填充到对应日期
        rawData.forEach(item -> {
            Integer day = (Integer) item.get("day");
            BigDecimal sales = new BigDecimal(item.get("sales").toString());
            salesMap.put(day, sales); // 覆盖默认的0值
        });

        // 4. 返回按1-31日排序的销售数据
        return new ArrayList<>(salesMap.values());
    }

    @Override
    public User getUserById(Integer userId) {
        return userDao.findByUserId(userId);
    }

    @Override
    public Product getProductById(Integer productId) {
        return productDao.selectByProductId(productId);
    }

    @Override
    public Order getOrderById(Integer orderId) {
        return orderDao.findOrderById(orderId);
    }

    @Override
    public List<User> getAllUsersWithPagination(int offset, int limit) {
        return adminDao.findAllUsersWithPagination(offset, limit);
    }

    @Override
    public List<User> searchUsersWithPagination(String keyword, int offset, int limit) {
        return adminDao.searchUsersWithPagination(keyword, offset, limit);
    }

    @Override
    public int countAllUsers() {
        return adminDao.countAllUsers();
    }

    @Override
    public List<Product> searchProductsWithPagination(String keyword, Integer categoryId, Integer status, String sort, int offset, int limit) {
        Map<String, Object> params = new HashMap<>();

        if (StringUtils.isNotBlank(keyword)) {
            params.put("keyword", "%" + keyword + "%");
        }

        if (categoryId != null) {
            params.put("categoryId", categoryId);
        }

        if (status != null) {
            params.put("status", status);
        }

        // 排序处理
        String orderBy = "createTime DESC"; // 默认排序
        if ("price_asc".equals(sort)) {
            orderBy = "price ASC";
        } else if ("price_desc".equals(sort)) {
            orderBy = "price DESC";
        }
        params.put("orderBy", orderBy);
        params.put("offset", offset);
        params.put("limit", limit);

        return adminDao.searchProductsWithPagination(params);
    }

    @Override
    public int countProducts(String keyword, Integer categoryId, Integer status) {
        Map<String, Object> params = new HashMap<>();

        if (StringUtils.isNotBlank(keyword)) {
            params.put("keyword", "%" + keyword + "%");
        }

        if (categoryId != null) {
            params.put("categoryId", categoryId);
        }

        if (status != null) {
            params.put("status", status);
        }

        return adminDao.countProducts(params);
    }

    @Override
    public List<Order> searchOrdersWithPagination(String keyword, Integer status, String timeRange, String sort, int offset, int limit) {
        Map<String, Object> params = new HashMap<>();

        if (StringUtils.isNotBlank(keyword)) {
            params.put("keyword", "%" + keyword + "%");
        }

        if (status != null) {
            params.put("status", status);
        }

        // 处理时间范围
        if (StringUtils.isNotBlank(timeRange)) {
            switch (timeRange) {
                case "today":
                    params.put("timeRange", "today");
                    break;
                case "week":
                    params.put("timeRange", "week");
                    break;
                case "month":
                    params.put("timeRange", "month");
                    break;
                default:
                    // "all" 或其他值不添加时间限制
                    break;
            }
        }

        // 处理排序
        String orderBy = "createTime DESC"; // 默认排序
        switch (sort) {
            case "oldest":
                orderBy = "createTime ASC";
                break;
            case "price_asc":
                orderBy = "price ASC";
                break;
            case "price_desc":
                orderBy = "price DESC";
                break;
            default:
                // "newest" 或其他值使用默认排序
                break;
        }
        params.put("orderBy", orderBy);
        params.put("offset", offset);
        params.put("limit", limit);

        return adminDao.searchOrdersWithPagination(params);
    }

    @Override
    public int countOrders(String keyword, Integer status, String timeRange) {
        Map<String, Object> params = new HashMap<>();

        if (StringUtils.isNotBlank(keyword)) {
            params.put("keyword", "%" + keyword + "%");
        }

        if (status != null) {
            params.put("status", status);
        }

        if (StringUtils.isNotBlank(timeRange)) {
            switch (timeRange) {
                case "today":
                    params.put("timeRange", "today");
                    break;
                case "week":
                    params.put("timeRange", "week");
                    break;
                case "month":
                    params.put("timeRange", "month");
                    break;
                default:
                    break;
            }
        }

        return adminDao.countOrders(params);
    }

    @Override
    public int deleteOrder(Integer orderId) {
        return adminDao.deleteOrders(orderId);
    }

    @Override
    public int countUsersByKeyword(String keyword) {
        return adminDao.countUsersByKeyword(keyword);
    }
}